<template>
  <div class="axiom-chart-container" :style="containerStyle">
    <canvas 
      ref="chartCanvas" 
      :width="width" 
      :height="height"
      v-if="!isEcharts"
    ></canvas>
    <div 
      ref="echartsContainer" 
      :style="{ width: width + 'px', height: height + 'px' }"
      v-if="isEcharts"
    ></div>
    <axiom-loading v-if="loading" text="正在生成图表..." size="small" />
    <axiom-text v-if="error" type="danger" size="small">{{ error }}</axiom-text>
  </div>
</template>

<script>
import { nextTick } from 'vue';
import AxiomLoading from './AxiomLoading.vue';
import AxiomText from './AxiomText.vue';
// import { GlobalUtilsMixin } from '@/utils/globalUtils';

export default {
  name: 'AxiomChart',
  components: {
    AxiomLoading,
    AxiomText,
  },
  // mixins: [GlobalUtilsMixin],
  props: {
    // 图表类型
    type: {
      type: String,
      required: true,
      validator: (value) => ['radar', 'line', 'bar', 'pie', 'doughnut', 'scatter'].includes(value)
    },
    // 图表数据
    data: {
      type: Object,
      required: true
    },
    // 图表配置选项
    options: {
      type: Object,
      default: () => ({})
    },
    // 尺寸
    width: {
      type: Number,
      default: 350
    },
    height: {
      type: Number,
      default: 250
    },
    // 响应式
    responsive: {
      type: Boolean,
      default: true
    },
    // 主题
    theme: {
      type: String,
      default: 'default'
    },
    // 使用 ECharts 还是 Chart.js
    engine: {
      type: String,
      default: 'echarts',
      validator: (value) => ['echarts', 'chartjs'].includes(value)
    }
  },
  emits: ['chartClick', 'chartReady'],
  data() {
    return {
      loading: false,
      error: null,
      chartInstance: null
    };
  },
  computed: {
    isEcharts() {
      return this.engine === 'echarts';
    },
    containerStyle() {
      return {
        position: 'relative',
        width: this.width + 'px',
        height: this.height + 'px',
        margin: '0 auto',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center'
      };
    }
  },
  watch: {
    data: {
      handler() {
        this.updateChart();
      },
      deep: true
    },
    options: {
      handler() {
        this.updateChart();
      },
      deep: true
    }
  },
  methods: {
    getDefaultOptions() {
      if (this.isEcharts) {
        return {
          tooltip: {
            trigger: 'item',
            backgroundColor: 'var(--axiom-bg-color)',
            borderColor: 'var(--axiom-border-color)',
            textStyle: {
              color: 'var(--axiom-text-color)'
            }
          },
          legend: {
            textStyle: {
              color: 'var(--axiom-text-color-secondary)'
            }
          },
          grid: {
            left: '10%',
            right: '10%',
            top: '15%',
            bottom: '15%'
          }
        };
      } else {
        return {
          responsive: this.responsive,
          maintainAspectRatio: false,
          plugins: {
            legend: {
              labels: {
                color: getComputedStyle(document.documentElement).getPropertyValue('--axiom-text-color').trim()
              }
            }
          },
          scales: this.type === 'radar' ? {} : {
            y: {
              ticks: {
                color: getComputedStyle(document.documentElement).getPropertyValue('--axiom-text-color-secondary').trim()
              },
              grid: {
                color: getComputedStyle(document.documentElement).getPropertyValue('--axiom-border-color').trim()
              }
            },
            x: {
              ticks: {
                color: getComputedStyle(document.documentElement).getPropertyValue('--axiom-text-color-secondary').trim()
              },
              grid: {
                color: getComputedStyle(document.documentElement).getPropertyValue('--axiom-border-color').trim()
              }
            }
          }
        };
      }
    },
    async createChart() {
      if (!this.data) return;
      
      this.loading = true;
      this.error = null;
      
      try {
        this.$perfMonitor.startTimer('chart-creation');
        
        if (this.isEcharts) {
          await this.createEchartsChart();
        } else {
          await this.createChartjsChart();
        }
        
        const duration = this.$perfMonitor.endTimer('chart-creation');
        // this.$logger.debug(`图表创建完成，耗时: ${duration}ms`);
        
        this.$emit('chartReady', this.chartInstance);
      } catch (err) {
        this.error = err.message || '图表创建失败';
        // this.$logger.error('图表创建失败:', err);
      } finally {
        this.loading = false;
      }
    },
    async createEchartsChart() {
      const echarts = await import('echarts/core');
      const { CanvasRenderer } = await import('echarts/renderers');
      
      if (this.type === 'radar') {
        const { RadarChart } = await import('echarts/charts');
        const { TitleComponent, TooltipComponent, LegendComponent } = await import('echarts/components');
        echarts.use([CanvasRenderer, RadarChart, TitleComponent, TooltipComponent, LegendComponent]);
      } else if (this.type === 'line') {
        const { LineChart } = await import('echarts/charts');
        const { GridComponent, TitleComponent, TooltipComponent, LegendComponent } = await import('echarts/components');
        echarts.use([CanvasRenderer, LineChart, GridComponent, TitleComponent, TooltipComponent, LegendComponent]);
      } else if (this.type === 'bar') {
        const { BarChart } = await import('echarts/charts');
        const { GridComponent, TitleComponent, TooltipComponent, LegendComponent } = await import('echarts/components');
        echarts.use([CanvasRenderer, BarChart, GridComponent, TitleComponent, TooltipComponent, LegendComponent]);
      } else if (this.type === 'pie') {
        const { PieChart } = await import('echarts/charts');
        const { TitleComponent, TooltipComponent, LegendComponent } = await import('echarts/components');
        echarts.use([CanvasRenderer, PieChart, TitleComponent, TooltipComponent, LegendComponent]);
      }
      
      this.chartInstance = echarts.init(this.$refs.echartsContainer);
      
      const option = {
        ...this.getDefaultOptions(),
        ...this.options,
        ...this.transformDataForEcharts()
      };
      
      this.chartInstance.setOption(option);
      
      this.chartInstance.on('click', (params) => {
        this.$emit('chartClick', params);
      });
    },
    async createChartjsChart() {
      const chartjs = await import('chart.js');
      const { Chart, registerables } = chartjs;
      Chart.register(...registerables);
      
      const ctx = this.$refs.chartCanvas.getContext('2d');
      
      this.chartInstance = new Chart(ctx, {
        type: this.type === 'doughnut' ? 'doughnut' : this.type,
        data: this.data,
        options: {
          ...this.getDefaultOptions(),
          ...this.options,
          onClick: (event, elements) => {
            if (elements.length > 0) {
              this.$emit('chartClick', { event, elements });
            }
          }
        }
      });
    },
    transformDataForEcharts() {
      const { data } = this;
      
      if (this.type === 'radar') {
        return {
          radar: {
            indicator: data.labels?.map(label => ({ name: label, max: 100 })) || []
          },
          series: [{
            type: 'radar',
            data: data.datasets?.map(dataset => ({
              value: dataset.data,
              name: dataset.label,
              lineStyle: {
                color: dataset.borderColor || 'var(--axiom-primary-color)'
              },
              areaStyle: {
                color: dataset.backgroundColor || 'var(--axiom-primary-color-light)'
              }
            })) || []
          }]
        };
      } else if (this.type === 'line') {
        return {
          xAxis: {
            type: 'category',
            data: data.labels || []
          },
          yAxis: {
            type: 'value'
          },
          series: data.datasets?.map(dataset => ({
            name: dataset.label,
            type: 'line',
            data: dataset.data,
            lineStyle: {
              color: dataset.borderColor || 'var(--axiom-primary-color)'
            }
          })) || []
        };
      } else if (this.type === 'bar') {
        return {
          xAxis: {
            type: 'category',
            data: data.labels || []
          },
          yAxis: {
            type: 'value'
          },
          series: data.datasets?.map(dataset => ({
            name: dataset.label,
            type: 'bar',
            data: dataset.data,
            itemStyle: {
              color: dataset.backgroundColor || 'var(--axiom-primary-color)'
            }
          })) || []
        };
      } else if (this.type === 'pie') {
        return {
          series: [{
            name: data.datasets?.[0]?.label || 'Data',
            type: 'pie',
            radius: '70%',
            data: data.labels?.map((label, index) => ({
              value: data.datasets?.[0]?.data?.[index] || 0,
              name: label
            })) || []
          }]
        };
      }
      
      return {};
    },
    updateChart() {
      if (!this.chartInstance) return;
      
      if (this.isEcharts) {
        const option = {
          ...this.getDefaultOptions(),
          ...this.options,
          ...this.transformDataForEcharts()
        };
        this.chartInstance.setOption(option, true);
      } else {
        this.chartInstance.data = this.data;
        this.chartInstance.options = {
          ...this.getDefaultOptions(),
          ...this.options
        };
        this.chartInstance.update();
      }
    },
    destroyChart() {
      if (this.chartInstance) {
        if (this.isEcharts) {
          this.chartInstance.dispose();
        } else {
          this.chartInstance.destroy();
        }
        this.chartInstance = null;
      }
    },
    getChartInstance() {
      return this.chartInstance;
    }
  },
  async mounted() {
    await nextTick();
    this.createChart();
  },
  unmounted() {
    this.destroyChart();
  }
};
</script>

<style lang="scss">
@use '../../styles/components/common/axiom-chart';
</style>